{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Predicciones Privadas con Syft Keras"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Paso 3: Solicitando Predicciones (Cliente)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Felicidades! Después de entrenar tu modelo con Keras y asegurarlo con Syft Keras, estás listo para solicitar predicciones privadas"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras.datasets import mnist\n",
    "\n",
    "import syft as sy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Datos"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Aquí vamos a preprocesar nuestros datos de MNIST. Esto es idéntico a como preprocesamos durante el aprendizaje"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Dimensiones de la imagen de entrada\n",
    "img_rows, img_cols = 28, 28\n",
    "\n",
    "# Divide los datos en aprendizaje y evaluación\n",
    "(x_train, y_train), (x_test, y_test) = mnist.load_data()\n",
    "\n",
    "x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)\n",
    "x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)\n",
    "input_shape = (img_rows, img_cols, 1)\n",
    "\n",
    "x_train = x_train.astype('float32')\n",
    "x_test = x_test.astype('float32')\n",
    "x_train /= 255\n",
    "x_test /= 255"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Conectando con el modelo"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Antes de enviar solicitudes al modelo, necesitas conectarte a él. Para esto, puedes crear un cliente. Luego define los mismos 3 TFEWorkers (`alice`, `bob` y `carol`) y clúster. Finalmente, llama `connect_to_model`. Esto crea un servidor TFE de colas en el lado del cliente que conecta al servidor de solicitudes que ha sido instaurado por `model.serve()` en la **Parte 13b**. La cola será responsable de compartir el secreto de datos antes de entregar las acciones en una solicitud de predicción."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "num_classes = 10\n",
    "input_shape = (1, 28, 28, 1)\n",
    "output_shape = (1, num_classes)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "client = sy.TFEWorker()\n",
    "\n",
    "alice = sy.TFEWorker(host='localhost:4000')\n",
    "bob = sy.TFEWorker(host='localhost:4001')\n",
    "carol = sy.TFEWorker(host='localhost:4002')\n",
    "cluster = sy.TFECluster(alice, bob, carol)\n",
    "\n",
    "client.connect_to_model(input_shape, output_shape, cluster)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Consultar el modelo!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Todo listo para obtener predicciones privadas! Ejecutando `query_model` insertará la `image` en la cola creada arriba, compartir el secreto de datos localmente, y entregar las acciones al servidor del modelo de la **Parte 13b**."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Parámetros del usuario\n",
    "num_tests = 3\n",
    "images, expected_labels = x_test[:num_tests], y_test[:num_tests]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for image, expected_label in zip(images, expected_labels):\n",
    "\n",
    "    res = client.query_model(image.reshape(1, 28, 28, 1))\n",
    "    predicted_label = np.argmax(res)\n",
    "\n",
    "    print(\"The image had label {} and was {} classified as {}\".format(\n",
    "        expected_label,\n",
    "        \"correctly\" if expected_label == predicted_label else \"wrongly\",\n",
    "        predicted_label))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Esto es genial. Ahora eres capaz de clasificar estas tres imágenes correctamente! Pero lo que es especial sobre estas predicciones es que tú no has tenido que revelar ninguna información privada para obtener este servicio. El host del modelo nunca vio tus datos de entrada o tus predicciones, y tu nunca descargaste el modelo. Pudiste obtener las predicciones de manera privada, con datos encriptados y un modelo encriptado!\n",
    "\n",
    "Antes de que nos apuremos a aplicar esto en nuestras apps, regresemos a la **Parte 13b** y limpiemos nuestro modelo!\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
